package ca.cbc.gisdigester.util;

import ca.cbc.giscommon.dao.EventSubcategoryDAO;
import ca.cbc.giscommon.entity.Event;
import ca.cbc.giscommon.entity.EventSubcategory;
import ca.cbc.giscommon.entity.Source;
import ca.cbc.giscommon.util.CalendarUtil;
import ca.cbc.giscommon.util.GeometryUtil;
import ca.cbc.giscommon.util.StringUtil;
import com.vividsolutions.jts.geom.Geometry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class FileMobileHelper {
    private static Logger logger = LoggerFactory.getLogger(FileMobileHelper.class);
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static List<Event> parseEvents(Document doc, Source source) {
        List<Event> events = new ArrayList<Event>();
        NodeList nodes = doc.getElementsByTagName("item");
        for (int i = 0; i < nodes.getLength(); i++) {
            Element item = (Element) nodes.item(i);
            String title = getFieldValue(item, "name");
            try {
                long endDate = parseFeedDate(getFieldValue(item, "endDate"));
                long startDate = parseFeedDate(getFieldValue(item, "startDate"));
                long created = parseFeedDate(getFieldValue(item, "created"));
                if (startDate <= 0) {
                    startDate = created;
                }

                if (endDate <= 0 || (endDate == startDate && startDate > 0)) {
                    endDate = CalendarUtil.instance.getEndTimeOfDay(startDate);
                }

                if (new Date().getTime() <= endDate && getFieldValue(item, "url") != null && !getFieldValue(item, "url").equals("")) {
	                Geometry theGeom = GeometryUtil.instance.parsePoint(
	                		Double.valueOf(getFieldValue(item, "geo_longitude")),
	                		Double.valueOf(getFieldValue(item, "geo_latitude"))
	                		);
	                    
	                Event e = new Event(title,// title
	                            getFieldValue(item, "url"), // link
	                            getFieldValue(item, "createdBy"),
	                            getFieldValue(item, "description"),
	                            created, //publishDate
	                            null, //audience
	                            null, //price
	                            null, //free
	                            startDate,
	                            endDate,
	                            null,//locationName
	                            getFieldValue(item, "address"),
	                            getFieldValue(item, "city"),
	                            getFieldValue(item, "state"),
	                            getFieldValue(item, "host"), //coordinator
	                            null, //email
	                            null, //phone
	                            null, //company
	                            null, //eventUrl
	                            null, //repeats
	                            getFieldValue(item, "postalcode"),
	                            source,
	                            theGeom
	                		);
	                EventSubcategory cat = parseEventSubcategory(getFieldValue(item, "custom1"));
	                    
	                if (cat != null) {
	                	List<EventSubcategory> cats = new ArrayList<EventSubcategory>();
	                	cats.add(cat);
	                	e.setEventSubcategories(cats);
	                }
	                events.add(e);
                }
            } catch (Exception e) {
                logger.error("Failed to process event: " + title, e);
            }
        }

        return events;
    }

    // Get string value of the field(fieldName) from element
    private static String getFieldValue(Element element, String fieldName) {
        NodeList nlList = element.getElementsByTagName(fieldName).item(0).getChildNodes();
        Node nValue = (Node) nlList.item(0);
        if (nValue != null)
            return StringUtil.instance.trimIfNotNull(nValue.getNodeValue());

        return null;
    }

    private static long parseFeedDate(String sdate) {
        if (StringUtil.instance.isNullOrEmpty(sdate))
            return -1;

        long d = -1;
        try {
            Date date = sdf.parse(sdate);
            d = date.getTime();
        } catch (ParseException e) {
            logger.error("parseFeedDate failed: {}", sdate, e);
        }
        return d;
    }

    private static EventSubcategory parseEventSubcategory(String category) {
        if (StringUtil.instance.isNullOrEmpty(category))
            return null;
        EventSubcategory cat = null;
        try {
            long id = Long.valueOf(category);
            cat = new EventSubcategoryDAO().findById(id);
        } catch (Exception e) {
            logger.error("parseFeedCategory failed: {}", category, e);
        }
        return cat;
    }
}
